package com.iqiyi.pps.epg.core.service.record;

import com.alibaba.fastjson.JSONObject;
import com.iqiyi.pps.epg.api.model.web.query.TFilter;
import com.iqiyi.pps.epg.api.model.web.query.TPage;
import com.iqiyi.pps.epg.api.model.web.record.*;
import com.iqiyi.pps.epg.core.dao.base.Page;
import com.iqiyi.pps.epg.core.dao.record.*;
import com.iqiyi.pps.epg.core.model.record.*;
import com.iqiyi.pps.epg.core.utils.ApiRecordNotifyUtil;
import com.iqiyi.pps.epg.core.utils.Constants;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by karkarrotxu on 2018/4/11.
 */
@Service
@Transactional
public class RecordServiceImpl implements IRecordService {
    protected Logger logger = LoggerFactory.getLogger(RecordServiceImpl.class);
    @Autowired
    private RecordPlanDao recordPlanDao;

    @Autowired
    private RecordTaskDao recordTaskDao;

    @Autowired
    private RecordVideoDao recordVideoDao;

    @Autowired
    private RecordTaskRuleDao recordTaskRuleDao;

    @Autowired
    private RecordChannelDao recordChannelDao;
    @Autowired
    private RecordColDao recordColDao;
    @Autowired
    private RecordSignalDao recordSignalDao;

    @Autowired
    private RecordChannelSignalDao recordChannelSignalDao;
    @Autowired
    private RecordChannelSignalTableDao recordChannelSignalTableDao;


    @Autowired
    private IRecordAsyncService recordAsyncService;

    @Override
    public long saveRecordPlan(RecordPlan entity) {
        recordPlanDao.saveOnly(entity);
        return entity.getId();
    }


    @Override
    public long saveRecordTaskRule(RecordTaskRule entity) {
        recordTaskRuleDao.saveOnly(entity);
        return entity.getId();
    }


    @Override
    public void editRecordPlan(RecordPlan entity) {
        recordPlanDao.save(entity);
    }

    @Override
    public void editRecordTaskRule(RecordTaskRule entity) {
        recordTaskRuleDao.save(entity);
    }

    @Override
    public TRecordPlanPage findPlanPage(TPage page, TFilter filter) {
        return recordPlanDao.findPlanPage(page, filter);
    }

    public TRecordPlan transToTRecordPlan(RecordPlan tempData) {
        return recordPlanDao.transToTRecordPlan(tempData);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public TRecordPlanLibraryPage findPlanLibraryPage(TPage page, TFilter filter) {
        return recordPlanDao.findLibraryPage(page, filter);
    }

    @Override
    public RecordPlan getRecordPlanById(long entityId) {
        return recordPlanDao.get(entityId);
    }


    @Override
    public List<RecordPlan> queryPlanByCriterion(List<Criterion> list, List<Order> orderList) {
        Criteria criteria = recordPlanDao.createCriteria();
        for (Criterion temp : list) {
            criteria.add(temp);
        }
        if (orderList != null) {
            for (Order tempOrder : orderList) {
                criteria.addOrder(tempOrder);
            }
        }
        return recordPlanDao.find(criteria);
    }

    @Override
    public void updateBatchRecordPlan(List<RecordPlan> plans) {
        recordPlanDao.batchUpdate(plans);
    }

    @Override
    public TRecordChannelSimplePage findChannelSimplePage(TPage page, TFilter filter) {
        return recordChannelDao.findChannelSimplePage(page, filter);
    }

    @Override
    public TRecordColSimplePage findColSimplePage(TPage page, TFilter filter) {
        return recordColDao.findColSimplePage(page, filter);
    }

    @Override
    public long saveRecordChannel(RecordChannel entity) {
        recordChannelDao.saveOnly(entity);
        return entity.getId();
    }

    @Override
    public void editRecordChannel(RecordChannel entity) {
        recordChannelDao.save(entity);
    }

    @Override
    public RecordChannel getRecordChannelById(long entityId) {
        return recordChannelDao.get(entityId);
    }


    @Override
    public void editRecordTask(RecordTask entity) {
        recordTaskDao.save(entity);
    }

    @Override
    public TRecordTaskDataPage findTaskDataPage(TPage page, TFilter filter) {
        return recordTaskDao.findTaskPage(page, filter);
    }

    @Override
    public TRecordTaskLibraryPage findTaskLibraryPage(TPage page, TFilter filter) {
        return recordTaskDao.findTaskLibraryPage(page, filter);
    }

    @Override
    public RecordTask getRecordTaskById(long entityId) {
        return recordTaskDao.get(entityId);
    }

    @Override
    public void saveBatchRecordTask(List<RecordTask> list) {
        recordTaskDao.batchSave(list);
    }

    @Override
    public void updateBatchRecordTask(List<RecordTask> list) {
        recordTaskDao.batchUpdate(list);
    }

    @Override
    public void doClearTaskBefore(long planId, long newStartTime){
        recordTaskDao.doClearTaskBefore( planId,newStartTime );
    }

    @Override
    public TRecordChannelPage findChannelPage(TPage page, TFilter filter) {
        Page<RecordChannel> pageData = recordChannelDao.findChannelPage(page, filter);
        List<RecordChannel> dataList = pageData.getResult();
        TRecordChannelPage dataPage = new TRecordChannelPage();
        page.setTotalCount(pageData.getTotalCount());
        dataPage.setTPage(page);
        List<TRecordChannel> tList = recordChannelDao.transToTRecordChannelList(dataList);
        dataPage.setResult(tList);
        return dataPage;
    }

    @Override
    public void delRecordChannel(long channelId) {
        recordChannelDao.delRecordChannel(channelId);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<RecordTaskRule> queryTaskRuleByCriterion(List<Criterion> list, List<Order> orderList) {
        Criteria criteria = recordTaskRuleDao.createCriteria();
        for (Criterion temp : list) {
            criteria.add(temp);
        }
        if (orderList != null) {
            for (Order tempOrder : orderList) {
                criteria.addOrder(tempOrder);
            }
        }
        return recordTaskRuleDao.find(criteria);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<RecordTask> queryTaskByCriterion(List<Criterion> list, List<Order> orderList) {
        return queryTaskByCriterion(list, orderList, -1);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<RecordTask> queryTaskByCriterion(List<Criterion> list, List<Order> orderList, int maxResultNum) {
        Criteria criteria = recordTaskDao.createCriteria();
        for (Criterion temp : list) {
            criteria.add(temp);
        }
        if (maxResultNum != -1) {
            criteria.setMaxResults(maxResultNum);
        }
        if (orderList != null) {
            for (Order tempOrder : orderList) {
                criteria.addOrder(tempOrder);
            }
        }
        return recordTaskDao.find(criteria);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<RecordTask> queryTaskByCriterion(List<Criterion> list, List<Order> orderList, int maxResultNum, int firstResult) {
        Criteria criteria = recordTaskDao.createCriteria();
        for (Criterion temp : list) {
            criteria.add(temp);
        }
        if (maxResultNum != -1) {
            criteria.setMaxResults(maxResultNum);
        }
        if (firstResult > -1) {
            criteria.setFirstResult(firstResult);
        }
        if (orderList != null) {
            for (Order tempOrder : orderList) {
                criteria.addOrder(tempOrder);
            }
        }
        return recordTaskDao.find(criteria);
    }


    @Override
    public int changeTaskRuleStatus(long planId, int execStatusNew, int execStatusOld) {
        logger.info("[changeTaskRuleStatus][planId={}][execStatusNew={}][execStatusOld={}]", planId, execStatusNew, execStatusOld);
        String hql = "update RecordTaskRule set status = ? where planId = ? and status = ? ";
        int executeUpdate = recordTaskRuleDao.createQuery(hql).setInteger(0, execStatusNew).setLong(1, planId).setInteger(2, execStatusOld).executeUpdate();
        logger.info("[changeTaskRuleStatus][executeUpdate={}]", executeUpdate);
        if (executeUpdate > 0) {
            return 1;
        }
        {
            return 0;
        }
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public RecordTaskRule getRecordTaskRuleByPlanId(long planId) {
        List<RecordTaskRule> list = recordTaskRuleDao.findBy("planId", planId);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public RecordTaskRule getRecordTaskRuleById(long entityId) {
        return recordTaskRuleDao.get(entityId);
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public TRecordSignalPage findSignalPage(TPage page, TFilter filter) {
        return recordSignalDao.findSignalPage(page, filter);
    }

    @Override
    public long saveRecordSignal(RecordSignal entity) {
        String sqlGetByName = "SELECT id FROM `record_signal` WHERE signal_name= '" + entity.getSignalName() + "'";
        List results = recordSignalDao.getSession().createSQLQuery(sqlGetByName).list();
        if (results.size() == 0) {
            recordSignalDao.saveOnly(entity);
            return 0;
        } else {
            return -1;
        }
    }


    @Override
    public TRecordSignal transToTRecordSignal(RecordSignal tempData) {
        TRecordSignal _tEntity = new TRecordSignal();
        if (tempData == null) {
            return _tEntity;
        }
        _tEntity.setId(tempData.getId());
        _tEntity.setSignalName(tempData.getSignalName());
        _tEntity.setSignalAddress(tempData.getSignalAddress());
        _tEntity.setPriority(tempData.getPriority());
        _tEntity.setServerCluster(tempData.getServerCluster());
        _tEntity.setOpUser(tempData.getOpUser());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        _tEntity.setCreateTime(sdf.format(tempData.getCreateTime()));
        _tEntity.setStatus(tempData.getStatus());
        return _tEntity;
    }

    @Override
    public void editRecordSignal(RecordSignal entity) {
        recordSignalDao.save(entity);
    }

    @Override
    public RecordSignal getRecordSignalById(long entityId) {
        return recordSignalDao.get(entityId);
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public TRecordChannelSignalPage findChannelSignalPage(TPage page, TFilter filter) {
        return recordChannelSignalDao.findChannelSignalPage(page, filter);
    }

    @Override
    public long saveRecordChannelSignal(RecordChannelSignal entity) {
        String sqlGetBySignalId = "SELECT id FROM `record_channel_signal` WHERE signal_id = " + entity.getSignalId() + " AND `status` <> -1 AND channel_id = " + entity.getChannelId();
        List results = recordSignalDao.getSession().createSQLQuery(sqlGetBySignalId).list();
        if (results.size() == 0) { //不重复
            calculateServerIp(entity);
            recordChannelSignalDao.saveOnly(entity);
            logger.info("[saveRecordChannelSignal][entity={}]", entity);
            return 0;
        } else { //重复
            logger.error("[saveRecordChannelSignal][already exist]");
            return -1;
        }
    }

    @Override
    public boolean delRecordChannelSignal(long id) {
        try {
            RecordChannelSignal recordChannelSignal = getRecordChannelSignalById(id);
            if (recordChannelSignal == null) {
                logger.warn("[deleteRecordChannelSignal] no such id {}", id);
                return false;
            }
            //判断状态是否启动收录，未启动则直接逻辑删除
            if (recordChannelSignal.getStatus() != 1) {
                recordChannelSignal.setStatus(-1);
                editRecordChannelSignal(recordChannelSignal);
                return true;
            }

            JSONObject jsonObject = ApiRecordNotifyUtil.notifyStop(recordChannelSignal.getId(), recordChannelSignal.getServerIp());
            logger.info("deleteRecordChannelSignal -> stopRecordChannelSignal[id=" + id + "][address=" + recordChannelSignal.getServerIp() + "]" + "][result=" + jsonObject.toJSONString() + "]");
            if (Constants.CODE_SUC.equals(jsonObject.getString("code"))) {
                recordChannelSignal.setStatus(-1);
                editRecordChannelSignal(recordChannelSignal);
                return true;
            } else {
                //暂时不 care 直接删除
                recordChannelSignal.setStatus(-1);
                editRecordChannelSignal(recordChannelSignal);
                logger.error("deleteRecordChannelSignal exception : stop error !!![id=" + id + "][address=" + recordChannelSignal.getServerIp() + "]" + "][result=" + jsonObject.toJSONString() + "]");
                return true;
            }
        } catch (Exception e) {
            logger.error("deleteRecordChannelSignal exception {}", e);
            return false;
        }
    }

    private void calculateServerIp(RecordChannelSignal entity) {
        //计算serverIp 获取当前服务器集群中的剩余最大收录数的ip
        //数据库查询 signal_id -> signal.server_cluster -> server_cluster.id ->server_ip.cluster_id inside_server_ip
        String sqlGetServerIp = "SELECT ips.inside_server_ip, COUNT(rcs.server_ip) , ips.max_including , (ips.max_including - COUNT(ips.inside_server_ip)) AS availableServer " +
                "FROM ( SELECT serverIp.inside_server_ip, serverIp.max_including " +
                "FROM `record_signal` recordSignal, `server_cluster` serverCluster, `server_ip` serverIp " +
                "WHERE recordSignal.id = " + entity.getSignalId() + " AND serverIp.`status` = 1 AND recordSignal.`status`= 1 AND recordSignal.server_cluster = serverCluster.`name` AND serverCluster.id = serverIp.cluster_id ) ips " +
                "LEFT JOIN record_channel_signal rcs ON rcs.`status` = 1 AND rcs.server_ip = ips.inside_server_ip " +
                "GROUP BY ips.inside_server_ip " +
                "ORDER BY availableServer DESC";
        List resultList = recordChannelSignalDao.getSession().createSQLQuery(sqlGetServerIp).list();
        if (resultList.size() > 0) {
            Object[] result = (Object[]) resultList.get(0);
            String serverIp = result[0] + "";
            String usedServer = result[1] + "";
            String maxServer = result[2] + "";
            String availableServer = result[3] + "";
            logger.info("[calculateServerIp][serverIp={}][usedServer={}][maxServer={}][availableServer={}]", serverIp, usedServer, maxServer, availableServer);
            entity.setServerIp(serverIp);
        } else {
            entity.setServerIp(null);
        }
        logger.info("[calculateServerIp][resultSize={}][serverIp={}]", resultList.size(), entity.getServerIp());

    }


    @Override
    public TRecordChannelSignal transToTRecordChannelSignal(long recordChannelSignalId) {
        TRecordChannelSignal _tEntity = new TRecordChannelSignal();
        if (recordChannelSignalId == 0) {
            return _tEntity;
        }
        //转为一次查询
        String sqlForSignalAndChannel = "SELECT recordChannelSignal.id, recordChannelSignal.signal_id, recordChannelSignal.channel_id, recordSignal.signal_name, recordSignal.signal_address , recordSignal.priority, recordSignal.server_cluster, recordChannelSignal.server_ip, recordChannel.channel_name, recordChannel.channel_code , recordChannelSignal.op_user, recordChannelSignal.create_time, recordChannelSignal.STATUS FROM record_channel_signal recordChannelSignal, record_channel recordChannel, record_signal recordSignal " +
                "WHERE recordChannelSignal.id = " + recordChannelSignalId + " AND recordSignal.STATUS <> -1 AND recordChannelSignal.signal_id = recordSignal.id AND recordChannelSignal.channel_id = recordChannel.id";
        Object[] obj = (Object[]) recordChannelSignalDao.getSession().createSQLQuery(sqlForSignalAndChannel).list().get(0);

        _tEntity.setId(Long.valueOf("" + obj[0]));
        _tEntity.setSignalId(Long.valueOf("" + obj[1]));
        _tEntity.setChannelId(Long.valueOf("" + obj[2]));
        _tEntity.setSignalName("" + obj[3]);
        _tEntity.setSignalAddress("" + obj[4]);
        _tEntity.setPriority(Integer.parseInt("" + obj[5]));
        _tEntity.setServerCluster("" + obj[6]);
        _tEntity.setServerIp("" + obj[7]);
        _tEntity.setChannelName("" + obj[8]);
        _tEntity.setChannelCode("" + obj[9]);
        _tEntity.setOpUser("" + obj[10]);
        _tEntity.setCreateTime("" + obj[11]);
        _tEntity.setStatus(Integer.parseInt("" + obj[12]));

        return _tEntity;
    }

    @Override
    public TRecordChannelSignal getTRecordChannelSignal(long id) {
        String resultPattern = "recordChannelSignal.id, recordChannelSignal.signal_id, recordChannelSignal.channel_id, recordSignal.signal_name, recordSignal.signal_address , recordSignal.priority, recordSignal.server_cluster, recordChannelSignal.server_ip, recordChannel.channel_name, recordChannel.channel_code , recordChannelSignal.op_user, recordChannelSignal.create_time, recordChannelSignal.STATUS  ";
        String sql = "select " + resultPattern + " FROM record_channel_signal recordChannelSignal, record_channel recordChannel, record_signal recordSignal WHERE recordChannelSignal.id = " + id + " AND recordChannelSignal.status <> -1 AND recordChannelSignal.signal_id = recordSignal.id AND recordChannelSignal.channel_id = recordChannel.id ";
        Object[] obj = (Object[]) recordChannelSignalDao.getSession().createSQLQuery(sql).uniqueResult();
        TRecordChannelSignal singleData = null;
        if (obj != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            singleData = new TRecordChannelSignal();
            singleData.setId(Long.valueOf("" + obj[0]));
            singleData.setSignalId(Long.valueOf("" + obj[1]));
            singleData.setChannelId(Long.valueOf("" + obj[2]));
            singleData.setSignalName(obj[3] == null ? null : "" + obj[3]);
            singleData.setSignalAddress(obj[4] == null ? null : "" + obj[4]);
            singleData.setPriority(Integer.valueOf("" + obj[5]));
            singleData.setServerCluster(obj[6] == null ? null : "" + obj[6]);
            singleData.setServerIp(obj[7] == null ? null : "" + obj[7]);
            singleData.setChannelName(obj[8] == null ? null : "" + obj[8]);
            singleData.setChannelCode(obj[9] == null ? null : "" + obj[9]);
            singleData.setOpUser(obj[10] == null ? null : "" + obj[10]);
            singleData.setCreateTime(sdf.format(obj[11]));
            singleData.setStatus(Integer.valueOf("" + obj[12]));
        }
        return singleData;
    }


    @Override
    public void editRecordChannelSignal(RecordChannelSignal entity) {
        recordChannelSignalDao.save(entity);
    }

    @Override
    public RecordChannelSignal getRecordChannelSignalById(long entityId) {
        return recordChannelSignalDao.get(entityId);
    }

    @Override
    public List<RecordChannelSignal> getRecordChannelSignalBySignalId(long signalId) {
        return recordChannelSignalDao.findBy("signalId", signalId);
    }

    @Override
    public TRecordChannelSignalTablePage findRecordChannelSignalTablePage(TPage page, TFilter filter) {
        return recordChannelSignalTableDao.find(page, filter);
    }

    @Override
    public void updateRecordChannelSignalStatus(long signalId, long status) {
        String updateSql = "UPDATE `record_channel_signal` SET `status` = " + status + " WHERE id = " + signalId + " AND status <> -1";
        int executeUpdate = recordChannelSignalDao.getSession().createSQLQuery(updateSql).executeUpdate();
        logger.info("[updateRecordChannelSignalStatus][signalId={}][executeUpdate={}]", signalId, executeUpdate);
    }

    @Override
    public int getServerAvailableIncluding(long recordChannelSignalId, String serverIp) {
        try {
            String sql = "SELECT ( SELECT COUNT(*) FROM `record_channel_signal` " +
                    "WHERE server_ip = '" + serverIp + "' AND `status` = 1 ) AS used_including, si.max_including, rcs.server_ip, rcs.id , rcs.signal_id , rcs.channel_id, si.cluster_id " +
                    "FROM record_channel_signal rcs, record_signal rs, server_ip si, server_cluster sc " +
                    "WHERE rcs.id = " + recordChannelSignalId + "  AND sc.`status` = 1 AND si.`status` = 1 AND rcs.signal_id = rs.id AND rs.server_cluster = sc.`name` AND sc.id = si.cluster_id AND si.inside_server_ip = rcs.server_ip";

            List sqlList = recordChannelSignalDao.getSession().createSQLQuery(sql).list();

            if (sqlList.size() > 0) {
                Object[] result = (Object[]) sqlList.get(0);
                String _usedIncluding = result[0] + "";
                String _maxIncluding = result[1] + "";
                String _serverIp = result[2] + "";
                String _recordChannelSignalId = result[3] + "";
                String _signalId = result[4] + "";
                String _channelId = result[5] + "";
                String _clusterId = result[6] + "";
                logger.info("[getServerAvailableIncluding][_usedIncluding={}][_maxIncluding={}][_serverIp={}][_recordChannelSignalId={}][_signalId={}][_channelId={}][_clusterId={}]", _usedIncluding, _maxIncluding, _serverIp, _recordChannelSignalId, _signalId, _channelId, _clusterId);
                return Integer.valueOf(_maxIncluding) - Integer.valueOf(_usedIncluding);
            } else {
                logger.info("[getServerAvailableIncluding][recordChannelSignalId={}][serverIp={}][no data exist in database]", recordChannelSignalId, serverIp);
                return 0;
            }
        } catch (Exception e) {

            logger.error("[getServerAvailableIncluding][exception]", e);
            return -999;
        }
    }

    @Override
    public List<RecordTask> queryRecordTaskForGetVideo() {
        try {
/*            String sql = "SELECT recordTask.id, recordTask.plan_id, recordTask.task_status, recordTask.task_start_time, recordTask.task_stop_time , recordTask.`status`, recordChannelSignal.signal_id, recordChannel.channel_code, recordCol.col_name, recordCol.has_auth , recordCol.category_id, recordChannel.channel_name, recordChannelSignal.server_ip, recordChannelSignal.channel_id, recordChannelSignal.`id` AS rcs_id, recordChannel.has_caption " +
                    "FROM record_task recordTask, record_plan recordPlan, record_channel_signal recordChannelSignal, record_channel recordChannel, record_col recordCol " +
                    "WHERE recordTask.`status` = 1 AND recordTask. task_status = 100 " +
                    "AND recordTask.plan_id = recordPlan.id " +
                    "AND recordPlan.`status` = 1 " +
                    "AND recordChannelSignal.STATUS = 1 AND recordTask.task_stop_time <= DATE_SUB(NOW(), INTERVAL 5 MINUTE) " +
                    "AND recordPlan.channel_id = recordChannel.id " +
                    "AND recordPlan.col_id = recordCol.id " +
                    "AND recordChannelSignal.channel_id = recordChannel.id";*/
            String sql = "SELECT id, plan_id, task_status, task_start_time, task_stop_time , `status`, signal_id, channel_code, col_name, has_auth , category_id, channel_name, server_ip, channel_id, rcs_id , has_caption " +
                    "FROM ( SELECT recordTask.id, recordTask.plan_id, recordTask.task_status, recordTask.task_start_time, recordTask.task_stop_time , recordTask.`status`, recordChannel.channel_code, recordCol.col_name, recordCol.has_auth, recordCol.category_id , recordCol.channel_id, recordChannel.channel_name, recordChannel.has_caption FROM record_task recordTask, record_plan recordPlan, record_channel recordChannel, record_col recordCol WHERE recordTask.`status` = 1 AND recordTask.task_status = 100 AND recordTask.plan_id = recordPlan.id AND recordPlan.`status` = 1 AND recordTask.task_stop_time <= DATE_SUB(NOW(), INTERVAL 5 MINUTE) AND recordPlan.channel_id = recordChannel.id AND recordPlan.col_id = recordCol.id AND recordCol.channel_id = recordChannel.id ) table1, " +
                    "( SELECT id AS rcs_id, channel_id AS rcs_channel_id, signal_id, server_ip FROM record_channel_signal WHERE `status` = 1 ) rcs " +
                    "WHERE table1.channel_id = rcs.rcs_channel_id";

            List result = recordChannelSignalDao.getSession().createSQLQuery(sql).list();
            List<RecordTask> recordTasks = new ArrayList<>();
            RecordTask recordTask = null;
            HashMap<String, String> params = null;
            for (Object single : result) {
                Object[] obj = (Object[]) single;
                recordTask = new RecordTask();
                recordTask.setId(Long.valueOf("" + obj[0]));
                recordTask.setPlanId(Long.valueOf("" + obj[1]));
                recordTask.setTaskStatus(Integer.valueOf("" + obj[2]));
                recordTask.setTaskStartTime("" + obj[3]);
                recordTask.setTaskStopTime("" + obj[4]);
                recordTask.setStatus(Integer.valueOf("" + obj[5]));
                //params
                params = new HashMap<>();
                params.put("signal_id", "" + obj[6]);
                params.put("channel_code", "" + obj[7]);
                params.put("taskname", "" + obj[8]);
                params.put("copyright", "" + obj[9]);
                params.put("classfy", "" + obj[10]);
                params.put("channel_name", "" + obj[11]);
                params.put("material_name", obj[8] + "_" + recordTask.getTaskStartTime());
                params.put("serverIp", "" + obj[12]);
                params.put("channelId", "" + obj[13]);
                params.put("channelSignalId", "" + obj[14]);
                params.put("is_logo", "" + obj[15]);

                recordTask.setParams(params);
                recordTasks.add(recordTask);
            }

            return recordTasks;
        } catch (Exception e) {
            logger.error("[queryRecordTaskForGetVideo][exception]", e);
            return new ArrayList<>();
        }
    }

    @Override
    public void saveRecordVideo(RecordVideo entity) {
        recordVideoDao.save(entity);
    }

    @Override
    public RecordVideo updateRecordVideoStatus(long signalId, long taskId, long videoId, int videoStatus) {
        //查询 signalId 视频是否存在 ，存在更新 ，返回
        try {
            RecordVideo recordVideo = recordVideoDao.getBySignalIdAndTaskId(signalId, taskId);
            if (recordVideo != null) {
                //更新所有信号
                recordVideo.setVideoId(videoId);
                recordVideo.setVideoStatus(videoStatus);
                recordVideoDao.save(recordVideo);
                logger.info("[updateRecordVideoStatus][signalId={}][recordVideo={}]", signalId, recordVideo);

            } else {
                logger.info("[updateRecordVideoStatus][notFound][signalId={}][recordVideo=null]", signalId);
            }
            return recordVideo;
        } catch (Exception e) {
            logger.error("[updateRecordVideoStatus][exception]", e);
            return null;

        }
    }


    @Override
    public RecordTask updateRecordTaskStatus(long taskId, int taskStatus) {
        //查询 taskId 是否存在 ，存在更新 ，返回
        try {
            RecordTask recordTask = recordTaskDao.get(taskId);
            if (recordTask != null) {
                //更新所有task
                recordTask.setTaskStatus(taskStatus);
                recordTaskDao.save(recordTask);
                if (taskStatus == RecordTaskStatus.NOTIFY_START_RECORD_FAIL.getStatusIndex()
                        || taskStatus == RecordTaskStatus.TASK_START_FAIL.getStatusIndex()
                        || taskStatus == RecordTaskStatus.TASK_START_UPLOAD_FAIL.getStatusIndex()) {
                    //更新 video 收录失败
                    recordVideoDao.updateByTaskId(taskId, RecordVideoStatus.RECORD_FAIL.getStatusIndex());
                    logger.info("[updateRecordTaskStatus][updateRecordVideoStatus][taskId={}]", taskId);

                }

                logger.info("[updateRecordTaskStatus][taskId={}][recordTask={}]", taskId, recordTask);

            } else {
                logger.info("[updateRecordTaskStatus][notFound][taskId={}][recordTask=null]", taskId);
            }
            return recordTask;
        } catch (Exception e) {
            logger.error("[updateRecordTaskStatus][exception]", e);
            return null;

        }
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<RecordCol> queryColByCriterion(List<Criterion> list, List<Order> orderList) {
        Criteria criteria = recordColDao.createCriteria();
        for (Criterion temp : list) {
            criteria.add(temp);
        }
        if (orderList != null) {
            for (Order tempOrder : orderList) {
                criteria.addOrder(tempOrder);
            }
        }
        return recordColDao.find(criteria);
    }


    public void updateBatchRecordCol(List<RecordCol> list) {
        recordColDao.batchUpdate(list);
    }

    @Override
    public void deleteVideoByChannel(long entityId) {
        recordVideoDao.deleteVideoByChannel(entityId);
    }

    @Override
    public void deleteVideoByTask(long taskId) {
        recordVideoDao.deleteVideoByTask(taskId);
    }

    @Override
    public void deleteVideoByTasks(String taskIds) {
        recordVideoDao.deleteVideoByTasks(taskIds.replaceAll("\\[|\\]|\\s", ""));
    }

    @Override
    public List<RecordChannelSignal> queryChannelSignalByCriterion(List<Criterion> list, List<Order> orderList) {
        Criteria criteria = recordChannelSignalTableDao.createCriteria();
        for (Criterion temp : list) {
            criteria.add(temp);
        }
        if (orderList != null) {
            for (Order tempOrder : orderList) {
                criteria.addOrder(tempOrder);
            }
        }
        return recordChannelSignalTableDao.find(criteria);
    }
}
